<template>
  <div class="corpus-management">
    <el-card class="page-header">
      <h2>语料库管理</h2>
      <p>管理系统中的句子对数据，支持上传、编辑、审核和删除操作</p>
    </el-card>

    <!-- 操作工具栏 -->
    <el-card class="toolbar-card">
      <div class="toolbar">
        <!-- 上传语料库 -->
        <div class="upload-section">
          <el-upload
            ref="uploadRef"
            :action="uploadAction"
            :headers="uploadHeaders"
            :data="uploadData"
            :before-upload="beforeUpload"
            :on-success="onUploadSuccess"
            :on-error="onUploadError"
            :show-file-list="false"
            accept=".txt"
          >
            <el-button type="primary" :icon="Upload">
              上传语料库
            </el-button>
          </el-upload>
          <span class="upload-tip">支持.txt格式，格式：lang1:text1|||lang2:text2</span>
        </div>

        <!-- 批量操作 -->
        <div class="batch-actions">
          <el-button 
            type="success" 
            :disabled="selectedPairs.length === 0"
            @click="batchUpdateStatus('approved')"
            :icon="Check"
          >
            批量通过
          </el-button>
          <el-button 
            type="warning" 
            :disabled="selectedPairs.length === 0"
            @click="batchUpdateStatus('rejected')"
            :icon="Close"
          >
            批量拒绝
          </el-button>
          <el-button 
            type="danger" 
            :disabled="selectedPairs.length === 0"
            @click="batchDelete"
            :icon="Delete"
          >
            批量删除
          </el-button>
        </div>

        <!-- 新增句子对 -->
        <el-button type="primary" @click="showCreateDialog" :icon="Plus">
          新增句子对
        </el-button>
      </div>

      <!-- 搜索和筛选 -->
      <div class="filters">
        <el-row :gutter="20">
          <el-col :span="6">
            <el-input
              v-model="searchForm.search"
              placeholder="搜索文本内容"
              :prefix-icon="Search"
              clearable
              @clear="handleSearch"
              @keyup.enter="handleSearch"
            />
          </el-col>
          <el-col :span="4">
            <el-select v-model="searchForm.lang1" placeholder="第一语言" clearable>
              <el-option label="中文" value="zh" />
              <el-option label="泰语" value="th" />
              <el-option label="越南语" value="vi" />
              <el-option label="印尼语" value="id" />
              <el-option label="马来语" value="ms" />
            </el-select>
          </el-col>
          <el-col :span="4">
            <el-select v-model="searchForm.lang2" placeholder="第二语言" clearable>
              <el-option label="中文" value="zh" />
              <el-option label="泰语" value="th" />
              <el-option label="越南语" value="vi" />
              <el-option label="印尼语" value="id" />
              <el-option label="马来语" value="ms" />
            </el-select>
          </el-col>
          <el-col :span="4">
            <el-select v-model="searchForm.status" placeholder="状态" clearable>
              <el-option label="待审核" value="pending" />
              <el-option label="已通过" value="approved" />
              <el-option label="已拒绝" value="rejected" />
            </el-select>
          </el-col>
          <el-col :span="4">
            <el-select v-model="searchForm.source" placeholder="来源" clearable>
              <el-option
                v-for="item in sourceOptions"
                :key="`filter-${item.value}`"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-col>
          <el-col :span="2">
            <el-button type="primary" @click="handleSearch" :icon="Search">
              搜索
            </el-button>
          </el-col>
        </el-row>
      </div>
    </el-card>

    <!-- 数据表格 -->
    <el-card class="table-card">
      <el-table
        v-loading="loading"
        :data="sentencePairs"
        @selection-change="handleSelectionChange"
        stripe
        style="width: 100%"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column prop="lang1" label="语言1" width="80" />
        <el-table-column prop="text1" label="文本1" min-width="200" show-overflow-tooltip />
        <el-table-column prop="lang2" label="语言2" width="80" />
        <el-table-column prop="text2" label="文本2" min-width="200" show-overflow-tooltip />
        <el-table-column prop="source" label="来源" width="120">
          <template #default="{ row }">
            <el-tag :type="getSourceTagType(row.source)">
              {{ getSourceText(row.source) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="getStatusTagType(row.status)">
              {{ getStatusText(row.status) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="uploader" label="上传者" width="120">
          <template #default="{ row }">
            {{ row.uploader ? row.uploader.username : '-' }}
          </template>
        </el-table-column>
        <el-table-column prop="created_at" label="创建时间" width="180">
          <template #default="{ row }">
            {{ formatDate(row.created_at) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="{ row }">
            <el-button size="small" @click="showEditDialog(row)" :icon="Edit">
              编辑
            </el-button>
            <el-button 
              size="small" 
              type="danger" 
              @click="deleteSentencePair(row)"
              :icon="Delete"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div class="pagination-wrapper">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.per_page"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 创建/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogTitle"
      width="600px"
      @close="resetForm"
    >
      <el-form
        ref="formRef"
        :model="form"
        :rules="formRules"
        label-width="110px"
      >
        <el-form-item label="句子对ID" prop="id">
          <el-input
            v-model="form.id"
            placeholder="留空则自动生成"
            :disabled="isEdit"
          />
        </el-form-item>
        <el-form-item label="第一语言" prop="lang1">
          <el-select v-model="form.lang1" placeholder="选择语言">
            <el-option
              v-for="item in languageOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="第一文本" prop="text1">
          <el-input
            v-model="form.text1"
            type="textarea"
            :rows="3"
            placeholder="请输入第一种语言的文本"
            maxlength="1000"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="第二语言" prop="lang2">
          <el-select v-model="form.lang2" placeholder="选择语言">
            <el-option
              v-for="item in languageOptions"
              :key="`lang2-${item.value}`"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="第二文本" prop="text2">
          <el-input
            v-model="form.text2"
            type="textarea"
            :rows="3"
            placeholder="请输入第二种语言的文本"
            maxlength="1000"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="form.status" placeholder="选择状态">
            <el-option
              v-for="item in statusOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="来源" prop="source">
          <el-select v-model="form.source" placeholder="选择来源">
            <el-option
              v-for="item in sourceOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="上传者ID" prop="uploaded_by">
          <el-input
            v-model="form.uploaded_by"
            placeholder="请输入上传用户ID"
          />
        </el-form-item>
        <el-form-item label="创建时间" prop="created_at">
          <el-date-picker
            v-model="form.created_at"
            type="datetime"
            placeholder="请选择创建时间"
            format="YYYY-MM-DD HH:mm:ss"
            value-format="YYYY-MM-DD HH:mm:ss"
            :default-time="['00:00:00']"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitForm" :loading="submitting">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  Upload, Check, Close, Delete, Plus, Search, Edit 
} from '@element-plus/icons-vue'
import { admin } from '@/api'

// 响应式数据
const loading = ref(false)
const submitting = ref(false)
const dialogVisible = ref(false)
const isEdit = ref(false)
const editId = ref(null)
const selectedPairs = ref([])
const sentencePairs = ref([])
const currentUser = ref(null)

// 分页数据
const pagination = reactive({
  page: 1,
  per_page: 20,
  total: 0,
  pages: 0,
  has_prev: false,
  has_next: false
})

// 搜索表单
const searchForm = reactive({
  search: '',
  lang1: '',
  lang2: '',
  status: '',
  source: ''
})

// 表单数据
const form = reactive({
  id: '',
  lang1: '',
  text1: '',
  lang2: '',
  text2: '',
  status: 'approved',
  source: 'manual',
  uploaded_by: '',
  created_at: ''
})

// 表单引用
const formRef = ref()
const uploadRef = ref()

const languageOptions = [
  { label: '中文', value: 'zh' },
  { label: '泰语', value: 'th' },
  { label: '越南语', value: 'vi' },
  { label: '印尼语', value: 'id' },
  { label: '马来语', value: 'ms' }
]

const statusOptions = [
  { label: '待审核', value: 'pending' },
  { label: '已通过', value: 'approved' },
  { label: '已拒绝', value: 'rejected' }
]

const sourceOptions = [
  { label: '手动录入', value: 'manual' },
  { label: '自动对齐生成', value: 'auto' },
  { label: 'LLM生成', value: 'llm' },
  { label: '管理员上传', value: 'admin_upload' },
  { label: '管理员创建', value: 'admin_create' }
]

const allowedLanguageCodes = languageOptions.map(item => item.value)
const allowedStatus = statusOptions.map(item => item.value)
const allowedSources = sourceOptions.map(item => item.value)

const validatePositiveInteger = (rule, value, callback) => {
  if (value === '' || value === null || value === undefined) {
    return callback()
  }
  const num = Number(value)
  if (!Number.isInteger(num) || num <= 0) {
    return callback(new Error('请输入合法的正整数'))
  }
  callback()
}

const validateRequiredInteger = (rule, value, callback) => {
  if (value === '' || value === null || value === undefined) {
    return callback(new Error('该字段为必填项'))
  }
  const num = Number(value)
  if (!Number.isInteger(num) || num <= 0) {
    return callback(new Error('请输入合法的正整数'))
  }
  callback()
}

const validateLanguageCode = (rule, value, callback) => {
  if (!value) {
    return callback(new Error('请选择语言'))
  }
  if (!allowedLanguageCodes.includes(value)) {
    return callback(new Error('请选择有效的语言代码'))
  }
  callback()
}

const validateStatus = (rule, value, callback) => {
  if (!value) {
    return callback(new Error('请选择状态'))
  }
  if (!allowedStatus.includes(value)) {
    return callback(new Error('请选择有效的状态'))
  }
  callback()
}

const validateSource = (rule, value, callback) => {
  if (!value) {
    return callback(new Error('请选择来源'))
  }
  if (!allowedSources.includes(value)) {
    return callback(new Error('请选择有效的来源'))
  }
  callback()
}

const validateDateTime = (rule, value, callback) => {
  if (!value) {
    return callback(new Error('请选择创建时间'))
  }
  const time = new Date(value.replace(/-/g, '/'))
  if (Number.isNaN(time.getTime())) {
    return callback(new Error('请输入有效的日期时间'))
  }
  callback()
}

const formatDateTime = (date) => {
  if (!date) return ''
  const d = typeof date === 'string' ? new Date(date) : date
  if (Number.isNaN(d.getTime())) return ''
  const pad = (n) => n.toString().padStart(2, '0')
  const year = d.getFullYear()
  const month = pad(d.getMonth() + 1)
  const day = pad(d.getDate())
  const hours = pad(d.getHours())
  const minutes = pad(d.getMinutes())
  const seconds = pad(d.getSeconds())
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

// 表单验证规则
const formRules = {
  id: [
    { validator: validatePositiveInteger, trigger: 'blur' }
  ],
  lang1: [
    { validator: validateLanguageCode, trigger: 'change' }
  ],
  text1: [
    { required: true, message: '请输入第一文本', trigger: 'blur' },
    { max: 1000, message: '文本长度不能超过1000个字符', trigger: 'blur' }
  ],
  lang2: [
    { validator: validateLanguageCode, trigger: 'change' }
  ],
  text2: [
    { required: true, message: '请输入第二文本', trigger: 'blur' },
    { max: 1000, message: '文本长度不能超过1000个字符', trigger: 'blur' }
  ],
  status: [
    { validator: validateStatus, trigger: 'change' }
  ],
  source: [
    { validator: validateSource, trigger: 'change' }
  ],
  uploaded_by: [
    { validator: validateRequiredInteger, trigger: 'blur' }
  ],
  created_at: [
    { validator: validateDateTime, trigger: 'change' }
  ]
}

// 计算属性
const dialogTitle = computed(() => isEdit.value ? '编辑句子对' : '新增句子对')

const uploadAction = computed(() => {
  // 直接使用与api/index.js中相同的baseURL
  return 'http://127.0.0.1:5000/api/upload-corpus'
})

const uploadHeaders = computed(() => {
  const token = localStorage.getItem('token')
  return token ? { Authorization: `Bearer ${token}` } : {}
})

const uploadData = computed(() => {
  const uploadedBy = getDefaultUploadedBy()
  return uploadedBy ? { uploaded_by: uploadedBy } : {}
})

const loadCurrentUser = () => {
  try {
    const userStorage = localStorage.getItem('user')
    currentUser.value = userStorage ? JSON.parse(userStorage) : null
  } catch (error) {
    currentUser.value = null
  }
}

const getDefaultUploadedBy = () => {
  return currentUser.value?.id ? Number(currentUser.value.id) : ''
}

const initializeForm = () => {
  Object.assign(form, {
    id: '',
    lang1: '',
    text1: '',
    lang2: '',
    text2: '',
    status: 'approved',
    source: 'manual',
    uploaded_by: getDefaultUploadedBy(),
    created_at: formatDateTime(new Date())
  })
}

const buildPayload = () => {
  const payload = {
    lang1: form.lang1,
    text1: form.text1.trim(),
    lang2: form.lang2,
    text2: form.text2.trim(),
    status: form.status,
    source: form.source,
    uploaded_by: form.uploaded_by === '' ? null : Number(form.uploaded_by),
    created_at: form.created_at
  }

  if (!isEdit.value && form.id !== '' && form.id !== null) {
    payload.id = Number(form.id)
  }

  Object.keys(payload).forEach((key) => {
    if (payload[key] === null || payload[key] === '' || payload[key] === undefined) {
      delete payload[key]
    }
  })

  return payload
}

// 方法
const fetchSentencePairs = async () => {
  loading.value = true
  try {
    const params = {
      page: pagination.page,
      per_page: pagination.per_page,
      ...searchForm
    }
    
    // 过滤空值
    Object.keys(params).forEach(key => {
      if (params[key] === '' || params[key] === null || params[key] === undefined) {
        delete params[key]
      }
    })

    const response = await admin.getSentencePairs(params)
    sentencePairs.value = response.data.sentence_pairs
    Object.assign(pagination, response.data.pagination)
  } catch (error) {
    console.error('获取句子对列表失败:', error)
    ElMessage.error('获取句子对列表失败')
  } finally {
    loading.value = false
  }
}

const handleSearch = () => {
  pagination.page = 1
  fetchSentencePairs()
}

const handleSizeChange = (size) => {
  pagination.per_page = size
  pagination.page = 1
  fetchSentencePairs()
}

const handleCurrentChange = (page) => {
  pagination.page = page
  fetchSentencePairs()
}

const handleSelectionChange = (selection) => {
  selectedPairs.value = selection
}

const showCreateDialog = () => {
  isEdit.value = false
  editId.value = null
  resetForm()
  dialogVisible.value = true
}

const showEditDialog = (row) => {
  isEdit.value = true
  editId.value = row.id
  Object.assign(form, {
    id: row.id,
    lang1: row.lang1,
    text1: row.text1,
    lang2: row.lang2,
    text2: row.text2,
    status: row.status,
    source: row.source,
    uploaded_by: row.uploaded_by ?? '',
    created_at: formatDateTime(row.created_at)
  })
  dialogVisible.value = true
}

const resetForm = () => {
  if (formRef.value) {
    formRef.value.resetFields()
  }
  initializeForm()
}

const submitForm = async () => {
  if (!formRef.value) return
  
  try {
    await formRef.value.validate()
    submitting.value = true
    const payload = buildPayload()
    
    if (isEdit.value) {
      await admin.updateSentencePair(editId.value, payload)
      ElMessage.success('句子对更新成功')
    } else {
      await admin.createSentencePair(payload)
      ElMessage.success('句子对创建成功')
    }
    
    dialogVisible.value = false
    fetchSentencePairs()
  } catch (error) {
    console.error('提交失败:', error)
    ElMessage.error(error.response?.data?.message || '操作失败')
  } finally {
    submitting.value = false
  }
}

const deleteSentencePair = async (row) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除句子对 "${row.text1}" 吗？`,
      '确认删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    await admin.deleteSentencePair(row.id)
    ElMessage.success('句子对删除成功')
    fetchSentencePairs()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除失败:', error)
      ElMessage.error('删除失败')
    }
  }
}

const batchUpdateStatus = async (status) => {
  try {
    const statusText = getStatusText(status)
    await ElMessageBox.confirm(
      `确定要将选中的 ${selectedPairs.value.length} 个句子对状态设为"${statusText}"吗？`,
      '确认批量操作',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    const pairIds = selectedPairs.value.map(pair => pair.id)
    await admin.batchUpdateSentencePairsStatus({ pair_ids: pairIds, status })
    ElMessage.success(`批量${statusText}成功`)
    fetchSentencePairs()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('批量操作失败:', error)
      ElMessage.error('批量操作失败')
    }
  }
}

const batchDelete = async () => {
  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedPairs.value.length} 个句子对吗？此操作不可恢复！`,
      '确认批量删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    const pairIds = selectedPairs.value.map(pair => pair.id)
    await admin.batchDeleteSentencePairs({ pair_ids: pairIds })
    ElMessage.success('批量删除成功')
    fetchSentencePairs()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('批量删除失败:', error)
      ElMessage.error('批量删除失败')
    }
  }
}

// 上传相关方法
const beforeUpload = (file) => {
  const isValidType = file.type === 'text/plain' || file.name.endsWith('.txt')
  const isLt10M = file.size / 1024 / 1024 < 10

  if (!isValidType) {
    ElMessage.error('只能上传 .txt 格式的文件!')
    return false
  }
  if (!isLt10M) {
    ElMessage.error('上传文件大小不能超过 10MB!')
    return false
  }
  return true
}

const onUploadSuccess = (response) => {
  ElMessage.success(response.message || '语料库上传成功')
  fetchSentencePairs()
}

const onUploadError = (error) => {
  console.error('上传失败:', error)
  ElMessage.error('语料库上传失败')
}

// 工具方法
const getStatusText = (status) => {
  const statusMap = {
    pending: '待审核',
    approved: '已通过',
    rejected: '已拒绝'
  }
  return statusMap[status] || status
}

const getStatusTagType = (status) => {
  const typeMap = {
    pending: 'warning',
    approved: 'success',
    rejected: 'danger'
  }
  return typeMap[status] || ''
}

const getSourceText = (source) => {
  const sourceMap = {
    manual: '手动上传',
    admin_upload: '管理员上传',
    admin_create: '管理员创建',
    auto: '自动对齐生成',
    llm: 'LLM生成'
  }
  return sourceMap[source] || source
}

const getSourceTagType = (source) => {
  const typeMap = {
    manual: '',
    admin_upload: 'success',
    admin_create: 'primary',
    auto: 'warning',
    llm: 'info'
  }
  return typeMap[source] || ''
}

const formatDate = (dateString) => {
  return formatDateTime(dateString)
}

// 生命周期
onMounted(() => {
  loadCurrentUser()
  initializeForm()
  fetchSentencePairs()
})
</script>

<style scoped>
.corpus-management {
  padding: 20px;
}

.page-header {
  margin-bottom: 20px;
}

.page-header h2 {
  margin: 0 0 10px 0;
  color: #303133;
}

.page-header p {
  margin: 0;
  color: #606266;
}

.toolbar-card {
  margin-bottom: 20px;
}

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.upload-section {
  display: flex;
  align-items: center;
  gap: 10px;
}

.upload-tip {
  font-size: 12px;
  color: #909399;
}

.batch-actions {
  display: flex;
  gap: 10px;
}

.filters {
  border-top: 1px solid #ebeef5;
  padding-top: 20px;
}

.table-card {
  margin-bottom: 20px;
}

.pagination-wrapper {
  display: flex;
  justify-content: center;
  margin-top: 20px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

:deep(.el-table .el-table__cell) {
  padding: 8px 0;
}

:deep(.el-upload) {
  display: inline-block;
}
</style>
